﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Globalization;
using System.Reflection;
using System.Windows;

namespace Phone.Framework.Converters
{
    public interface ICommonConverter : IValueConverter
    {
        Type ConverterObject { get; set; }

        string ConverterMethod { get; set; }

        string ConvertBackMethod { get; set; }
    }

    public class CommonConverter : ICommonConverter, IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ConverterObject.GetMethod(ConverterMethod).Invoke(null, new object[] { value, targetType, parameter, culture });
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ConverterObject.GetMethod(ConvertBackMethod).Invoke(null, new object[] { value, targetType, parameter, culture });
        }

        public Type ConverterObject { get; set; }

        public string ConverterMethod { get; set; }

        public string ConvertBackMethod { get; set; }
    }

    public class ConverterProvider : IValueConverter
    {
        public ConverterProvider()
        {

        }

        private Type _converterObject;
        public Type ConverterObject
        {
            get
            {
                return _converterObject;
            }
            set
            {
                _converterObject = value;
                if (_converterObject != null)
                    ConverteObjectMethod();
            }
        }

        

        private void ConverteObjectMethod()
        {
            Converters = new Dictionary<string, ICommonConverter>();
            MemberInfo[] list = ConverterObject.GetMembers(BindingFlags.Static | BindingFlags.Public);
            foreach (var item in list)
            {
                if (!Converters.Where(e => !string.IsNullOrEmpty(e.Value.ConvertBackMethod)).Any(e=>e.Value.ConvertBackMethod.Equals(item.Name)))
                {
                    var converter = new CommonConverter() { ConverterObject = ConverterObject, ConverterMethod = item.Name };
                    var attribute = item.GetCustomAttributes(typeof(ConverterBackAttribute), false) as ConverterBackAttribute[];
                    if (attribute != null && attribute.Length > 0)
                        converter.ConvertBackMethod = attribute[0].ConvertBackMethod;

                    Converters.Add(item.Name, converter);
                }
            }
        }

        public Dictionary<string, ICommonConverter> Converters { get; set; }


        public object this[string index]
        {
            get { return Converters[index]; }
        }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string[] paramsArr = parameter.ToString().Split(new char[] { '|' });
            if (paramsArr.Length == 1)
                return Converters[parameter.ToString()].Convert(value, targetType, null, culture);
            if (paramsArr.Length == 3)
                return Converters[paramsArr[0]].Convert(value, targetType, paramsArr[2], culture);
            return Converters[paramsArr[0]].Convert(value, targetType, null, culture);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string[] paramsArr = parameter.ToString().Split(new char[] { '|' });
            if (paramsArr.Length == 2)
                return Converters[paramsArr[1]].ConvertBack(value, targetType, null, culture);
            if (paramsArr.Length == 3)
                return Converters[paramsArr[1]].ConvertBack(value, targetType, paramsArr[2], culture);
            return Converters[paramsArr[0]].ConvertBack(value, targetType, null, culture);
        }
        //"1|2|3"
    }

    public class ConverterBackAttribute : Attribute
    {
        public string ConvertBackMethod { get; set; }


    }

    public class ConverterExtension
    {
        [ConverterBackAttribute(ConvertBackMethod = "ArrayToStringBackConverter")]
        public static object ArrayToStringConverter(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var array = value as string[];
            if (array == null)
                return null;
            return String.Join(", ", array);
        }

        public static object ArrayToStringBackConverter(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var array = value as string[];
            if (array == null)
                return null;
            return String.Join(", ", array);
        }

        public static object LaborRule_SelectedIndexToBooleanConverter(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var selectedIndex = (int)value;
            if (selectedIndex < 5)
                return true;
            else
                return false;
          
        }

        public static object NullToBooleanConverter(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return false;
            return true;
        }

        public static object IntToPercentConverter(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return 0;
            return string.Format("{0}%",value);
            
        }

    }
}
